package com.cino.service;

import com.cino.entity.SysAuditLog;
import com.cino.mapper.AuditLogMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;

import java.util.Date;

/**
 * 异步审计日志服务
 */
@Slf4j
@Service
public class AsyncAuditLogService {

    @Autowired
    private AuditLogMapper auditLogMapper;

    /**
     * 异步保存审计日志（支持新增字段）
     * 
     * @param objectId      操作对象ID
     * @param objectType    对象类型（表名）
     * @param content       日志内容
     * @param operationType 操作类型
     * @param storageTable  自定义存储表名，如果为null或空则使用默认的audit_log表
     * @param auditStatus   审计状态：0代表失败，1代表成功
     * @param errorMessage  错误信息
     * @param duration      耗时时间（毫秒）
     * @param title         标题
     */
    @Async("auditLogExecutor")
    public void saveAuditLogAsync(String objectId, String objectType, String content, String operationType, 
                                 String storageTable, Integer auditStatus, String errorMessage, Long duration, String title) {
        try {
            // 创建审计日志实体
            SysAuditLog sysAuditLog = new SysAuditLog();
            sysAuditLog.setObjectId(objectId);
            sysAuditLog.setObjectType(objectType);
            sysAuditLog.setAuditContent(content);
            sysAuditLog.setOperationType(operationType);
            sysAuditLog.setCreateTime(new Date()); // 设置创建时间
            
            // 设置自定义存储表名
            sysAuditLog.setStorageTable(storageTable);
            
            // 设置新增字段（不设置默认值，由调用方决定）
            sysAuditLog.setAuditStatus(auditStatus);
            sysAuditLog.setErrorMessage(errorMessage);
            sysAuditLog.setDuration(duration);
            sysAuditLog.setTitle(title);

            // 异步保存审计日志
            // 注意：TableNameInterceptor会检查实体中的storageTable字段，
            // 如果有值则动态替换表名
            auditLogMapper.insert(sysAuditLog);

            log.info(">>> [线程:{}] 异步审计日志保存成功: {}", Thread.currentThread().getName(), sysAuditLog);

        } catch (Exception e) {
            log.error(">>> [线程:{}] 异步审计日志保存失败: {}", Thread.currentThread().getName(), e.getMessage(), e);
        }
    }

    /**
     * 异步保存审计日志 (实体对象方式)
     * 
     * @param sysAuditLog 审计日志实体（可包含storageTable字段指定自定义表名）
     */
    @Async("auditLogExecutor")
    public void saveAuditLogAsync(SysAuditLog sysAuditLog) {
        try {
            // 设置创建时间
            if (sysAuditLog.getCreateTime() == null) {
                sysAuditLog.setCreateTime(new Date());
            }

            // 异步保存审计日志
            // 注意：TableNameInterceptor会检查实体中的storageTable字段，
            // 如果有值则动态替换表名
            auditLogMapper.insert(sysAuditLog);

            log.info(">>> [线程:{}] 异步审计日志保存成功: {}", Thread.currentThread().getName(), sysAuditLog);

        } catch (Exception e) {
            log.error(">>> [线程:{}] 异步审计日志保存失败: {}", Thread.currentThread().getName(), e.getMessage(), e);
        }
    }
}
